﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System;
using System.Net.Http;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;




namespace OpenCvSharp
{
    public partial class Form1 : Form
    {
        // 双缓冲的位图
        private Bitmap bufferBitmap;
        private Graphics bufferGraphics;


        public Form1()
        {
            InitializeComponent();
        }


        /// <summary>
        /// 窗体加载
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Form1_Load(object sender, EventArgs e)
        {
            for (int i = 1; i < 10; i++)
            {
                cmbInterval.Items.Add(i.ToString());
            }
            cmbInterval.SelectedIndex = 0;

            LightPixelManager.shareMe().LoadPixelDataFromCSV("2907000A");
        }


        private void Form1_Shown(object sender, EventArgs e)
        {
            pictureBox1OnPaint();
        }

        // 1. 首先在窗体初始化时创建缓冲位图和图形对象
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            // 初始化双缓冲位图和图形对象
            bufferBitmap = new Bitmap(pictureBox1.Width, pictureBox1.Height);
            bufferGraphics = Graphics.FromImage(bufferBitmap);
        }

        // 2. 修正绘制方法
        private void pictureBox1OnPaint()
        {
            // 清除画布
            bufferGraphics.Clear(Color.Gray);

            foreach (PixelPoint device in LightPixelManager.shareMe().pixelPoints)
            {
                using (Brush brush = new SolidBrush(Color.Black))
                {
                    // 正确绘制控件位置和大小
                    bufferGraphics.FillRectangle(brush, device.X, device.Y, 4, 4);
                }
            }


            // 将缓冲位图绘制到 pictureBox1 上
            pictureBox1.Image = bufferBitmap;
            pictureBox1.Refresh();
        }



        ///*******************************************************************************
        /// <summary>
        /// 视频拆分成图片
        /// </summary>
        ///*******************************************************************************
        private void button1_Click(object sender, EventArgs e)
        {
            string newPath = "";
            int stepNum = cmbInterval.SelectedIndex;

            //选择视频文件
            OpenFileDialog GetData = new OpenFileDialog();
            GetData.Multiselect = false;
            GetData.Title = "请选择文件";
            GetData.Filter = "MP4 和 GIF 文件|*.mp4;*.gif";

            if (GetData.ShowDialog() == DialogResult.OK)
            {
                //创建文件夹
                try
                {
                    // 获取用户选择的文件完整路径
                    string selectedFilePath = GetData.FileName;
                    VideoBinEncoder.shareMe().ConvertVideoToFramePictures(selectedFilePath, stepNum, LightPixelManager.shareMe().pixelPoints, (progress) =>
                    {
                        lblShow.Text = "处理帧 " + progress.ToString();
                        // 确保UI更新
                        Application.DoEvents();
                    });
                }
                catch (Exception ex)
                {
                    Console.WriteLine("创建文件夹时发生错误: " + ex.Message);
                }
            }
        }



        ///*******************************************************************************
        /// <summary>
        /// 重新整理文件
        /// 按序号重新命名文件名
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        ///*******************************************************************************
        private void button2_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog folderDlg = new FolderBrowserDialog();
            DialogResult result = folderDlg.ShowDialog();

            if (result == DialogResult.OK && !string.IsNullOrWhiteSpace(folderDlg.SelectedPath))
            {
                string selectedFolderPath = folderDlg.SelectedPath;

                VideoBinEncoder.shareMe().SortAndNumberImages(selectedFolderPath, (progress) =>
                {
                    lblShow.Text = "处理帧 " + progress.ToString();
                    // 确保UI更新
                    Application.DoEvents();
                });
            }
        }



        /// <summary>
        /// 强制停止
        /// </summary>
        private void button4_Click(object sender, EventArgs e)
        {
            VideoBinEncoder.shareMe().stopConvert();
        }






        ///*******************************************************************************
        /// <summary>
        /// 将视频转成bin文件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        ///*******************************************************************************
        private void btnVedioToFile_Click(object sender, EventArgs e)
        {
            int stepNum = cmbInterval.SelectedIndex;

            //选择视频文件
            OpenFileDialog GetData = new OpenFileDialog();
            GetData.Multiselect = false;
            GetData.Title = "请选择文件";
            GetData.Filter = "MP4 和 GIF 文件|*.mp4;*.gif";

            if (GetData.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    // 记录开始时间
                    DateTime startTime = DateTime.Now;

                    string selectedFilePath = GetData.FileName;
                    VideoBinEncoder.shareMe().ConvertVideoToPixelBin(selectedFilePath, stepNum, LightPixelManager.shareMe().pixelPoints, (progress) =>
                    {

                        lblShow.Text = "处理帧 " + progress.ToString();
                        // 确保UI更新
                        Application.DoEvents();
                    });

                    // 计算处理时间
                    TimeSpan processingTime = DateTime.Now - startTime;
                    // 显示处理完成信息，包括处理时间和帧数
                    string message = $"操作已完成！\n {lblShow.Text} 帧\n处理时间: {processingTime.TotalSeconds:F2} 秒";
                    MessageBox.Show(message, "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);

                }
                catch (Exception ex)
                {
                    return;
                }
            }
        }


        /// <summary>
        /// 指定URL的视频拆解
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button3_Click(object sender, EventArgs e)
        {
            DownloadAndProcessVideo(lblShow);
        }





        // 在你的窗体类中添加以下方法
        public async Task DownloadAndProcessVideo(Label lblShow)
        {
            string videoUrl = "https://iot-ailightctrl.oss-cn-shanghai.aliyuncs.com/text2image/ai_sources/15_Dynamic_Sky_Clouds/Preview.mp4";

            // 修改路径到 pixdata 目录下，使用随机文件名
            string pixDataPath = Path.Combine(Application.StartupPath, "pixdata");

            // 确保 pixdata 目录存在
            if (!Directory.Exists(pixDataPath))
            {
                Directory.CreateDirectory(pixDataPath);
            }

            // 生成随机文件名
            string randomFileName = $"video_{Guid.NewGuid().ToString("N").Substring(0, 8)}.mp4";
            string localVideoPath = Path.Combine(pixDataPath, randomFileName);

            int stepNum = cmbInterval.SelectedIndex;



            try
            {
                // 记录开始下载时间
                DateTime startDownloadTime = DateTime.Now;

                lblShow.Text = "正在下载视频...";
                Application.DoEvents();

                // 下载视频文件
                await DownloadVideoAsync(videoUrl, localVideoPath, lblShow);

                lblShow.Text = "视频下载完成，开始处理...";
                Application.DoEvents();

                // 检查文件是否存在
                if (!File.Exists(localVideoPath))
                {
                    MessageBox.Show("视频文件下载失败", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }

                // ==========================
                // 记录视频加载时间
                DateTime startEncoderTime = DateTime.Now;

                // 使用VideoBinEncoder处理视频
                VideoBinEncoder.shareMe().ConvertVideoToPixelBin(localVideoPath, stepNum, LightPixelManager.shareMe().pixelPoints, (progress) =>
                {
                    lblShow.Text = "处理帧 " + progress.ToString();
                    // 确保UI更新
                    Application.DoEvents();
                });


                DateTime endTime = DateTime.Now;
                string message = $"下载时间: {(startEncoderTime - startDownloadTime).TotalSeconds:F2} 秒\n" +
                                 $"处理时间: {(endTime - startEncoderTime).TotalSeconds:F2} 秒\n" +
                                 $"总耗时: {(endTime - startDownloadTime).TotalSeconds:F2} 秒";

                MessageBox.Show(message, "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch (Exception ex)
            {
                MessageBox.Show($"处理过程中发生错误: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                lblShow.Text = "处理失败";
            }
        }



        /// <summary>
        /// 下载视频文件的方法（简化版）
        /// </summary>
        /// <param name="url"></param>
        /// <param name="filePath"></param>
        /// <param name="lblShow"></param>
        /// <returns></returns>
        private async Task DownloadVideoAsync(string url, string filePath, Label lblShow)
        {
            using (HttpClient client = new HttpClient())
            {
                // 设置优化的参数
                client.Timeout = TimeSpan.FromMinutes(10);
                client.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36");

                // 先获取文件信息
                using (HttpResponseMessage response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead))
                {
                    response.EnsureSuccessStatusCode();
                    long? totalBytes = response.Content.Headers.ContentLength;

                    // 显示文件大小
                    if (totalBytes.HasValue)
                    {
                        lblShow.Text = $"正在下载视频... (大小: {totalBytes.Value / (1024.0 * 1024.0):F2} MB)";
                        Application.DoEvents();
                    }

                    // 直接下载到文件
                    using (Stream contentStream = await response.Content.ReadAsStreamAsync())
                    using (FileStream fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None, 65536, useAsync: true))
                    {
                        await contentStream.CopyToAsync(fileStream, 65536); // 使用更大的缓冲区
                    }
                }
            }

            lblShow.Text = "视频下载完成，开始处理...";
            Application.DoEvents();
        }


        //private async Task DownloadVideoAsync(string url, string filePath, Label lblShow)
        //{
        //    using (HttpClient client = new HttpClient())
        //    {
        //        client.Timeout = TimeSpan.FromMinutes(10);

        //        using (HttpResponseMessage response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead))
        //        {
        //            response.EnsureSuccessStatusCode();

        //            long? totalBytes = response.Content.Headers.ContentLength;
        //            using (Stream contentStream = await response.Content.ReadAsStreamAsync())
        //            {
        //                var progress = new Progress<int>(percent =>
        //                {
        //                    lblShow.Text = $"正在下载视频... {percent}%";
        //                });
        //                await ProcessContentStream(contentStream, filePath, totalBytes, progress);
        //            }
        //        }
        //    }
        //}

        //private async Task ProcessContentStream(Stream contentStream, string filePath, long? totalBytes, IProgress<int> progress)
        //{
        //    const int bufferSize = 8192;
        //    byte[] buffer = new byte[bufferSize];
        //    long totalBytesRead = 0;
        //    int bytesRead;

        //    using (FileStream fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None, bufferSize, useAsync: true))
        //    {
        //        while ((bytesRead = await contentStream.ReadAsync(buffer, 0, buffer.Length)) > 0)
        //        {
        //            await fileStream.WriteAsync(buffer, 0, bytesRead);
        //            totalBytesRead += bytesRead;

        //            if (totalBytes.HasValue && progress != null)
        //            {
        //                int progressPercentage = (int)((totalBytesRead * 100) / totalBytes.Value);
        //                progress.Report(progressPercentage);
        //            }
        //        }
        //    }
        //}



        /// <summary>
        /// 下载视频文件的方法
        /// </summary>
        /// <param name="url"></param>
        /// <param name="filePath"></param>
        /// <param name="lblShow"></param>
        /// <returns></returns>
        //private async Task DownloadVideoAsync(string url, string filePath, Label lblShow)
        //{
        //    using (HttpClient client = new HttpClient())
        //    {
        //        // 设置超时时间
        //        client.Timeout = TimeSpan.FromMinutes(10);

        //        using (HttpResponseMessage response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead))
        //        {
        //            response.EnsureSuccessStatusCode();

        //            long? totalBytes = response.Content.Headers.ContentLength;
        //            using (Stream contentStream = await response.Content.ReadAsStreamAsync())
        //            {
        //                await ProcessContentStream(contentStream, filePath, totalBytes, lblShow);
        //            }
        //        }
        //    }
        //}

        // 处理内容流并显示进度
        private async Task ProcessContentStream(Stream contentStream, string filePath, long? totalBytes, Label lblShow)
        {
            const int bufferSize = 8192;
            byte[] buffer = new byte[bufferSize];
            long totalBytesRead = 0;
            int bytesRead;

            using (FileStream fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None, bufferSize, useAsync: true))
            {
                while ((bytesRead = await contentStream.ReadAsync(buffer, 0, buffer.Length)) > 0)
                {
                    await fileStream.WriteAsync(buffer, 0, bytesRead);
                    totalBytesRead += bytesRead;

                    // 更新下载进度
                    if (totalBytes.HasValue)
                    {
                        int progressPercentage = (int)((totalBytesRead * 100) / totalBytes.Value);
                        lblShow.Text = $"正在下载视频... {progressPercentage}%";
                        Application.DoEvents();
                    }
                }
            }
        }

        // 调用示例 - 在按钮点击事件或其他地方调用
        private async void btnDownloadAndProcess_Click(object sender, EventArgs e)
        {
            // 禁用按钮防止重复点击
            Button btn = sender as Button;
            if (btn != null)
            {
                btn.Enabled = false;
            }

            await DownloadAndProcessVideo(lblShow); // 假设lblShow是你的Label控件

            // 处理完成后重新启用按钮
            if (btn != null)
            {
                btn.Enabled = true;
            }
        }



    }

}
